package com.simple.async;

import android.os.Handler;
import android.os.Looper;

import java.lang.ref.WeakReference;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 线程池管理类
 */
public class TaskExecutor {

    //单例对象
    private static volatile TaskExecutor INSTANCE;

    //线程池
    private ThreadPoolExecutor mThreadPoolExecutor;

    private Object mObject = new Object();

    //线程池最大线程数
    private int maxThreadNum;

    public int getMaxThreadNum() {
        return maxThreadNum;
    }

    public void setMaxThreadNum(int maxThreadNum) {
        this.maxThreadNum = maxThreadNum;
    }

    private Handler mHandler;

    /**
     * 防止外部获取对象
     */
    private TaskExecutor() {
        maxThreadNum = 16;
        mHandler = new Handler(Looper.getMainLooper());
    }

    /**
     * 创建线程池
     */
    private void createOrExistThreadPool() {
        if (mThreadPoolExecutor == null) {
            synchronized (mObject) {
                if (mThreadPoolExecutor == null) {
                    mThreadPoolExecutor = new ThreadPoolExecutor(
                            3,
                            maxThreadNum,
                            30,
                            TimeUnit.SECONDS,
                            new LinkedBlockingDeque<>());
                }
            }
        }
    }

    /**
     * @param runnable 任务内容
     *                 使用线程池，执行耗时任务
     */
    private void execute(Runnable runnable) {
        createOrExistThreadPool();
        mThreadPoolExecutor.execute(runnable);
    }

    /**
     * @return 防止外部获取对象
     */
    private static TaskExecutor getInstance() {
        if (INSTANCE == null) {
            synchronized (TaskExecutor.class) {
                if (INSTANCE == null) {
                    INSTANCE = new TaskExecutor();
                }
            }
        }
        return INSTANCE;
    }

    /**
     * @param max 最大线程数
     *            设置线程池最大线程数
     *            需要在第一次使用线程池执行任务之前调用
     */
    public static void setMaxThread(int max) {
        getInstance().setMaxThreadNum(max);
    }

    /**
     * 获取线程池最大线程数
     */
    public static int getMaxThread() {
        return getInstance().getMaxThreadNum();

    }

    /**
     * @param runnable 任务内容
     *                 是用线程池执行异步任务
     */
    public static void executeTask(Runnable runnable) {
        getInstance().execute(runnable);
    }

    public static <R> void executeTask(Task<R> task, TaskResult<R> uiResult) {
        WeakReference<TaskResult> weakRef = new WeakReference<>(uiResult);
        getInstance().execute(() -> {
            R r = task.doInBackground();
            getInstance().mHandler.post(() -> {
                if (weakRef.get() != null) {
                    weakRef.get().onPostExecute(r);
                }
            });
        });
    }


}
